<template>
  <transition name="modal-fade">
    <popup type="modal" :mask="true" :center="true" v-show="isVisible">
      <div class="modal-main">
        <span class="modal-close" v-show="showClose" @click="close"></span>
        <div :class="containerClass">
          <p class="modal-icon" v-if="icon"><icon :icon="iconName" :color="iconColor" size="30"/></p>
          <h2 v-if="title || $slots.title" class="modal-title">
            <slot name="title">
              <p class="modal-title-def">{{title}}</p>
            </slot>
          </h2>
          <div class="modal-content">
            <slot name="content">
              <div class="modal-content-def">
                <p v-html="content"></p>
              </div>
            </slot>
          </div>
          <div class="modal-btns" :class="{'border-right-1px': isConfirm}">
            <slot name="btns">
              <a :href="_cancelBtn.href" class="modal-btn border-top-1px" :class="{'modal-btn_highlight': _cancelBtn.active}" v-if="isConfirm" @click="cancel">{{_cancelBtn.text}}</a>
              <a :href="_confirmBtn.href" class="modal-btn border-top-1px" :class="{'modal-btn_highlight': _confirmBtn.active}" @click="confirm">{{_confirmBtn.text}}</a>
            </slot>
          </div>
        </div>
      </div>
    </popup>
  </transition>
</template>

<script lang="ts">
import { Component, Emit, Prop, Mixins } from 'vue-property-decorator'
import ApiMixin from '../common/mixins/api'
import Popup from '../popup/popup.vue'
import Icon from '../icon/icon.vue'

const COMPONENT_NAME = 'modal'
const EVENT_CONFIRM = 'confirm'
const EVENT_CANCEL = 'cancel'
const EVENT_CLOSE = 'close'
const defHref = 'javascript:;'
const defConfirmBtn = {
  text: '确定',
  active: true,
  href: defHref
}
const defCancelBtn = {
  text: '取消',
  active: false,
  href: defHref
}
const parseBtn = (btn:string | object, defBtn:object) :object => {
  if (typeof btn === 'string') {
    btn = {
      text: btn
    }
  }
  return Object.assign({}, defBtn, btn)
}

@Component({
  name: COMPONENT_NAME,
  components: {
    Icon,
    Popup
  }
})
export default class Modal extends Mixins(ApiMixin) {
  @Prop({ default: 'alert' }) private type!:string
  @Prop({ default: '' }) private icon!:'danger' | 'info' | 'warn' | 'success'
  @Prop({ default: '' }) private title!:string
  @Prop({ default: '' }) private content!:string
  @Prop({ default: false }) private showClose!:boolean
  @Prop({
    default () {
      return {
        ...defConfirmBtn
      }
    }
  })
  private confirmBtn!:object | string
  @Prop({
    default () {
      return {
        ...defCancelBtn
      }
    }
  })
  private cancelBtn!:object | string

  private defHref:string = defHref

  private get _confirmBtn () {
    return parseBtn(this.confirmBtn, defConfirmBtn)
  }
  private get _cancelBtn () {
    return parseBtn(this.cancelBtn, defCancelBtn)
  }
  private get isConfirm ():boolean {
    return this.type === 'confirm'
  }
  private get containerClass ():string {
    return `modal-${this.type}`
  }
  private get iconColor ():string {
    enum colors {
      danger = '#E95E56',
      info = '3F86F5',
      warning = '#FFB400',
      success = '#41BD5A'
    }
    return colors[this.icon] || '#4a4c5b'
  }
  private get iconName () {
    enum iconNames {
      danger = 'close-fill',
      info = 'tip-fill',
      warning = 'tip-fill',
      success = 'correct-fill'
    }
    return iconNames[this.icon] || this.icon
  }
  @Emit(EVENT_CONFIRM)
  confirm (e:Event) {
    this.hide()
    return e
  }
  @Emit(EVENT_CANCEL)
  cancel (e:Event) {
    this.hide()
    return e
  }
  @Emit(EVENT_CLOSE)
  close (e:Event) {
    this.hide()
    return e
  }
}
</script>

<style lang="stylus">
  @import '../common/stylus/base'
  .modal-main {
    width: 270px;
    padding: 0;
    text-align: center;
    overflow: hidden;
    border-radius: 12px;
    background-color: $modal-bg-color;
  }
  .modal-confirm, .modal-alert {
    position: relative;
    overflow: hidden;
  }
  .modal-icon {
    margin-top: 20px;
    margin-bottom: 16px;
    line-height: 1;
    svg {
      display: inline-block;
      width: 30px;
      height: 30px;
      padding: 10px;
      border-radius: 50%;
      background-color: #f3f4f5;
    }
    + .modal-title {
      .modal-title-def {
        margin-top: 0;
      }
    }
    + .modal-content {
      margin-top: -4px;
    }
  }
  .modal-title {
    color: $modal-title-color;
    font-size: 16px;
    line-height: 1;
    + .modal-content {
      margin-top: 12px;
    }
  }
  .modal-title-def {
    margin: 30px 16px 0;
    overflow: hidden;
    white-space: nowrap;
  }
  .modal-content {
    margin: 16px 0;
    text-align: left;
    color: $modal-content-color;
    font-size: 14px;
    line-height: 22px;
  }
  .modal-content-def {
    padding: 0 16px;
    > p {
      display: table;
      margin: auto;
    }
  }
  .modal-confirm {
    .modal-btns {
      .modal-btn {
        width: 50%;
        float: left;
      }
      &.border-right-1px {
        &::after {
          right: 50%;
          border-color: #ebebeb;
        }
      }
    }
  }
  .icon-confirm {
    background-size: 262px 53px
  }
  .modal-close {
    position: absolute;
    top: 0;
    right: 0;
    width: 32px;
    height: 32px;
    z-index: 1;
    &:before {
      display: block;
      position: absolute;
      top: 50%;
      left: 6px;
      content: '';
      width: 20px;
      height: 1px;
      background-color: $modal-btn-color;
      transform: rotate(-45deg);
    }
    &:after {
      display: block;
      position: absolute;
      top: 50%;
      left: 6px;
      content: '';
      width: 20px;
      height: 1px;
      background-color: $modal-btn-color;
      transform: rotate(45deg);
    }
  }
  .modal-btns {
    overflow: hidden;
    width: 100%;
    font-size: 0;
  }
  .modal-btn {
    display: inline-block;
    width: 100%;
    padding: 17px 10px;
    margin: 0;
    font-size: 16px;
    line-height: 1;
    text-align: center;
    text-decoration: none;
    color: $modal-btn-color;
    background-color: $modal-bg-color;
    background-clip: padding-box;
    box-sizing: border-box;
    &:active {
      background-color: rgba(0, 0, 0, .04);
    }
  }
  .modal-btn_highlight {
    color: $modal-btn-active-color;
    &:active {
      background-color: rgba(252, 145, 83, .04);
    }
  }
  .modal-btn_disabled {
    color: $modal-btn-disable-color;
    &:active {
      background-color: transparent;
    }
  }
  .modal-fade-enter-active {
    animation: modal-fadein .4s;
    .modal-main {
      animation: modal-zoom .4s;
    }
  }
  @keyframes modal-fadein {
    0% {
      opacity: 0
    }
    100% {
      opacity: 1
    }
  }
  @keyframes modal-zoom {
    0% {
      transform: scale(0)
    }
    50% {
      transform: scale(1.1)
    }
    100% {
      transform: scale(1)
    }
  }
</style>
